using System.Collections;
using ValidationFramework.Extensions;
using ValidationFramework.Configuration.Xml;
using ValidationFramework.Configuration;
using ValidationFramework.Reflection;
namespace ValidationFramework.Specifications
{
	/// <summary>
	/// A <see cref="IRuleConfigReader"/> that creates a <see cref="LengthCollectionRule"/> from a <see cref="RuleData"/>.
	/// </summary>
	/// <remarks>
	///   <see cref="RuleData"/> for default attributes.
	///   <b>Extra Attributes</b>
	///   <ul>
	///     <li>
	///       <c>excludeDuplicatesFromCount</c> (optional): Used to populate <see cref="ValidationFramework.LengthCollectionRule.ExcludeDuplicatesFromCount"/>.  
	///     </li>
	///     <li>
	///       <c>minimum</c> (optional): Used to populate <see cref="ValidationFramework.LengthRule.Maximum"/>.   
	///     </li>
	///     <li>
	///       <c>maximum</c> (required): Used to populate <see cref="ValidationFramework.LengthRule.Minimum"/>.   
	///     </li>
	///   </ul>
	/// </remarks>
	/// <example>
	/// <code lang="xml" title="This example shows an xml configuration for LengthCollectionRuleConfigReader">
	/// <rule 
	/// errorMessage="hello" 
	/// excludeDuplicatesFromCount="true" 
	/// typeName="LengthCollectionRule" 
	/// minimum="1" 
	/// maximum="5"/>
	/// </code>
	/// </example>
	/// <seealso cref="LengthCollectionRule"/>
	/// <seealso cref="ConfigurationService"/>
	public sealed class HasCountInRangeParser : ISpecificationXmlParser
	{
		public ISpecification GetSpecification(System.Xml.XmlElement SpecificationElement, RuleContext context)
		{
			Guard.ArgumentNotNull(SpecificationElement, "SpecificationElement");

			var minimum = SpecificationElement.GetAttribute("minimum", 0);
			var maximum = SpecificationElement.GetAttribute<int>("maximum");
			var excludeDuplicatesFromCount = SpecificationElement.GetAttribute("excludeDuplicatesFromCount", true);

			var equalityComparerTypeName = SpecificationElement.GetAttribute<string>("equalityComparerTypeName", "");
			var equalityComparerPropertyName = SpecificationElement.GetAttribute<string>("equalityComparerPropertyName", "");
			var equalityComparer = (IEqualityComparer)TypeExtensions.GetStaticProperty(equalityComparerTypeName, equalityComparerPropertyName);

			return new HasCountInRangeSpec(minimum, maximum)
			{
				CountDuplicates = excludeDuplicatesFromCount,
				Comparer = equalityComparer
			};
		}
	}
}